﻿using SearchInFiles.Lib.Search;
using System;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

namespace SearchInFiles.Lib.Controls
{
    public class SearchResultHighlightTextblock : TextBlock
    {
        public SearchResultHighlightTextblock():base()
        {
            DataContextChanged += SearchResultHighlightTextblock_DataContextChanged;
        }

        private void SearchResultHighlightTextblock_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (e.OldValue != null && e.OldValue is SearchResult OldValue)
                OldValue.PropertyChanged -= SearchResult_PropertyChanged;

            if (e.NewValue != null && e.NewValue is SearchResult NewValue)
            {
                NewValue.PropertyChanged += SearchResult_PropertyChanged;
                UpdateHighText(NewValue);
            }
            else Text = null;
        }

        private void SearchResult_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            SearchResult sr = (SearchResult)sender!;
            if (e.PropertyName?.Equals(nameof(sr.HitString), StringComparison.OrdinalIgnoreCase) ?? false)
            {
                if (Thread.CurrentThread == Dispatcher.Thread)
                    UpdateHighText(sr);
                else
                    Dispatcher.BeginInvoke(() => UpdateHighText(sr));
            }
        }

        private void UpdateHighText(SearchResult searchResult)
        {
            Text = string.Empty;
            if (string.IsNullOrEmpty(searchResult.PartialContext))
                return;

            string[] spli = searchResult.PartialContext.Split(searchResult.HitString);
            for (int i = 0; i < spli.Length; i++)
            {
                Inlines.Add(new Run(spli[i]));

                if (i < spli.Length - 1)
                {
                    int searchstart = Text.Length;
                    var iCaseTextIndex = searchResult.PartialContext.IndexOf(searchResult.HitString, searchstart, StringComparison.OrdinalIgnoreCase);
                    if (iCaseTextIndex < 0)
                    {
                        continue;
                    }
                    string caseText = searchResult.PartialContext.Substring(iCaseTextIndex, searchResult.HitStringLength);
                    Inlines.Add(new Run(caseText) { Background = Brushes.Yellow });
                }
            }
        }
    }
}
